//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR INDEMNITIES.
//
//
// (C) Copyright 2006 Marvell International Ltd.
// All Rights Reserved
//
/******************************************************************************
**
** INTEL CONFIDENTIAL
** Copyright 2003-2005 Intel Corporation All Rights Reserved.
**
** The source code contained or described herein and all documents
** related to the source code (Material) are owned by Intel Corporation
** or its suppliers or licensors.  Title to the Material remains with
** Intel Corporation or its suppliers and licensors. The Material contains
** trade secrets and proprietary and confidential information of Intel
** or its suppliers and licensors. The Material is protected by worldwide
** copyright and trade secret laws and treaty provisions. No part of the
** Material may be used, copied, reproduced, modified, published, uploaded,
** posted, transmitted, distributed, or disclosed in any way without Intel's
** prior express written permission.
**
** No license under any patent, copyright, trade secret or other intellectual
** property right is granted to or conferred upon you by disclosure or
** delivery of the Materials, either expressly, by implication, inducement,
** estoppel or otherwise. Any license under such intellectual property rights
** must be express and approved by Intel in writing.
**
**
******************************************************************************/

#include <windows.h>
#include <nkintr.h>
#include <monahans.h>
#include <Littleton.h>
#include <oal_memory.h>
#include <pcireg.h>
#include <fmd.h>
#include <bsp.h>
#include "loader.h"
#include <bootpart.h>
#include "xllp_pm.h"
#include "xllp_pm_dvfm.h"
#include "monahans_base_regs.h"
#include "xllp_defs.h"
#include "xllp_udc.h"
#include "xllp_lcd_plat.h"

#include <flash_cfg.h>
#include <blcommon.h>

//Included for the SD/MMC boot option
#include "SDMMC.h"
#include "FAT.h"

#include "BLMenu.h"

extern BSP_ARGS *g_pBSPArgs ;

BOOL AreYouSure();
DWORD DetectLCDPanel();

/// Choose KITL Transport, both for image download and KITL debug
/// @param  *pItem   [IN] MENU_ITME
/// @return     1       Successful
DWORD SetKitlTrans(MENU_ITEM * pItem)
{

    BSP_ARGS *pArg=g_pBSPArgs;

    if( pItem->pParam2 == (VOID*) MONAHANS_BASE_REG_PA_USB2H)
    {
        EdbgOutputDebugString("\r\nWarning: If you use USB2.0 as Kitl, you will not be able to use usb2.0 as default usb function driver\r\n");

        if(! AreYouSure())
        {	// user canceled the request.
            return 1;
        }

    }

    OALBLMenuDWORDChoose(pItem);

    return 1;
}


    /// Detect type of LCD panel
    /// @param  *pItem   [IN] MENU_ITME
    /// @return     1       Successful
DWORD DetectLCDPanelMenuItem(MENU_ITEM * pItem)
{
    *(DWORD*)pItem->pParam1 = DetectLCDPanel();
    return 1;
}

    /// The implementation of LCD panel detec.
    /// @return     Panel type ID
DWORD DetectLCDPanel()
{
    XLLP_LCD_T XllpLCD;
    XLLP_UINT32_T panel_id;
    //XLLP_UINT32_T is_portrait;
    XLLP_STATUS_T status;

    XllpLCD.GPIO = (XLLP_VUINT32_T *)OALPAtoVA(MONAHANS_BASE_REG_PA_GPIO, FALSE);
    XllpLCD.MFP = (XLLP_VUINT32_T *) OALPAtoVA(MONAHANS_BASE_REG_PA_MFP, FALSE);
    XllpLCD.CLKMan = (XLLP_VUINT32_T *) OALPAtoVA(MONAHANS_BASE_REG_PA_CLKMGR, FALSE);
    XllpLCD.LCDC = (XLLP_VUINT32_T *) OALPAtoVA(MONAHANS_BASE_REG_PA_LCD, FALSE);
    XllpLCD.OST = (XLLP_VUINT32_T *) OALPAtoVA(MONAHANS_BASE_REG_PA_OST, FALSE);
    XllpLCD.pMfpRmDb = 0;

    /* TODO: should remove DetectLCDPanel - Littleton */
   status = XLLP_STATUS_FAILURE;
#if 0

    status = XllpLCDPanelDetect(&XllpLCD, &panel_id, &is_portrait);
    if (status != XLLP_STATUS_SUCCESS)
        EdbgOutputDebugString("\r\nXllpLCDPanelDetect failed!\r\n");
    EdbgOutputDebugString ("\r\nLCD_ID %x, orient %d\r\n", panel_id, is_portrait);
#endif

    if (status != XLLP_STATUS_SUCCESS)
        panel_id = XLLP_LCD_PANEL_ID_UNKNOWN;

    return panel_id;
}

    /// Map the LCD panel name to panel XLLP ID
    /// @param  panel   [IN] LCD Panel ID
    /// @return     text of the LCD name.
static LPCWSTR GetLCDPanelName(DWORD panel)
{
    switch(panel)
    {
    case XLLP_LCD_PANEL_ID_776C:
        return L"QVGA LTM035A776C";
    case XLLP_LCD_PANEL_ID_380K:
        return L"VGA LTM04C380K";
    case XLLP_LCD_PANEL_ID_VGA_QVGA_OLED_LEAD:
        return L"VGA/QVGA/OLED leaded";
    case XLLP_LCD_PANEL_ID_VGA_QVGA_OLED_LEAD_FREE:
        return L"VGA/QVGA/OLED lead free";
    case XLLP_LCD_PANEL_ID_VGA_QVGA_OLED_LEAD_FREE_LANDSCAPE:
        return L"VGA/QVGA/OLED lead free landscape";
    default:
        return L"unknown LCD panel";
    }
}

MENU_ITEM LCDPanelMenu[]=
{
    {L'1', L"QVGA LTM035A776C", OALBLMenuDWORDChoose,&(BSPARGS_START->eBootCFG.drvCfg[CFG_LCD_PANEL ]),(VOID*)XLLP_LCD_PANEL_ID_776C,NULL,NULL},
    {L'2', L"VGA LTM04C380K", OALBLMenuDWORDChoose, &(BSPARGS_START->eBootCFG.drvCfg[CFG_LCD_PANEL ]),(VOID*)XLLP_LCD_PANEL_ID_380K,NULL,NULL},
    {L'3', L"VGA/QVGA/OLED leaded", OALBLMenuDWORDChoose, &(BSPARGS_START->eBootCFG.drvCfg[CFG_LCD_PANEL ]),(VOID*)XLLP_LCD_PANEL_ID_VGA_QVGA_OLED_LEAD,NULL,NULL},
    {L'4', L"VGA/QVGA/OLED lead free", OALBLMenuDWORDChoose, &(BSPARGS_START->eBootCFG.drvCfg[CFG_LCD_PANEL ]),(VOID*)XLLP_LCD_PANEL_ID_VGA_QVGA_OLED_LEAD_FREE_LANDSCAPE,NULL,NULL},
    {L'D', L"Detect panel type", DetectLCDPanelMenuItem, &(BSPARGS_START->eBootCFG.drvCfg[CFG_LCD_PANEL ]),(VOID *) 100000,NULL,NULL},
    
    {L'Q', L"Quit",NULL,NULL,NULL,NULL,NULL},
    
    {0,NULL,NULL,NULL,NULL,NULL,NULL}
};

MENU_ITEM BlitMenu[]=
{
    {L'G', L"GCU", OALBLMenuDWORDChoose,&(BSPARGS_START->DefaultBlit),(VOID*)BSP_ARGS_BLIT_GCU,NULL,NULL},
    {L'X', L"XScale software optimized", OALBLMenuDWORDChoose, &(BSPARGS_START->DefaultBlit),(VOID*)BSP_ARGS_BLIT_OPT,NULL,NULL},
    {L'E', L"Emulated", OALBLMenuDWORDChoose, &(BSPARGS_START->DefaultBlit),(VOID*)BSP_ARGS_BLIT_EMU,NULL,NULL},
    {L'Q', L"Quit",NULL,NULL,NULL,NULL,NULL},

    {0,NULL,NULL,NULL,NULL,NULL,NULL}
};

/// map Blit implementation text name to its ID.
/// @param  blit_type   [IN] which type of Blit
/// @return     text of the Blit implementation name
static LPCWSTR GetBlitName(DWORD blit_type)
{
    switch (blit_type)
    {
    case BSP_ARGS_BLIT_GCU:
        return L"GCU";
    case BSP_ARGS_BLIT_OPT:
        return L"Software optimized";
    case BSP_ARGS_BLIT_EMU:
        return L"Emulated";
    default:
        return L"Unknown";
    }
}


MENU_ITEM SensorMenu[]=
{
    {L'1', L"OV7670", OALBLMenuDWORDChoose, &(BSPARGS_START->DefaultSensor),(VOID *) BSP_ARGS_OV7670,NULL,NULL},
    {L'2', L"OV5623", OALBLMenuDWORDChoose, &(BSPARGS_START->DefaultSensor),(VOID *) BSP_ARGS_OV5623,NULL,NULL},    
    {L'Q', L"Quit",NULL,NULL,NULL,NULL,NULL},
    
    {0,NULL,NULL,NULL,NULL,NULL,NULL}
};


MENU_ITEM KITLTransMenu[]=
{

    {L'1',L"SMC LAN91", SetKitlTrans, &(BSPARGS_START->kitl.devLoc.PhysicalLoc), (VOID*)(LITTLETON_BASE_REG_PA_SMSC_ETHERNET + 0x300),NULL,NULL},
    {L'2',L"USB 2.0 RNDIS",SetKitlTrans,&(BSPARGS_START->kitl.devLoc.PhysicalLoc), (VOID*)MONAHANS_BASE_REG_PA_USB2H,NULL,NULL},
    {L'Q', L"Quit",NULL,NULL,NULL,NULL,NULL},

    {0,NULL,NULL,NULL,NULL,NULL,NULL}		
};

MENU_ITEM STUARTMenu[]=
{
    {L'1', L"Debug Serial", OALBLMenuDWORDChoose,&(BSPARGS_START->STUARTUsage),(VOID*)BSP_ARGS_STUART_DEBUG_SERIAL,NULL,NULL},
    {L'2', L"IRDA", OALBLMenuDWORDChoose, &(BSPARGS_START->STUARTUsage),(VOID*)BSP_ARGS_STUART_IRDAL,NULL,NULL},
    {L'Q', L"Quit",NULL,NULL,NULL,NULL,NULL},

    {0,NULL,NULL,NULL,NULL,NULL,NULL}
};

MENU_ITEM BTWLANMenu[]=
{
    {L'1', L"No Tech Board", OALBLMenuDWORDChoose,&(BSPARGS_START->TechBoardUsage),(VOID*)BSP_ARGS_TECHBOARD_NONE,NULL,NULL},
    {L'2', L"BaseBand board", OALBLMenuDWORDChoose, &(BSPARGS_START->TechBoardUsage),(VOID*)BSP_ARGS_TECHBOARD_BASEBAND,NULL,NULL},
    {L'3', L"WLAN only Board", OALBLMenuDWORDChoose, &(BSPARGS_START->TechBoardUsage),(VOID*)BSP_ARGS_TECHBOARD_WLAN,NULL,NULL},
    {L'4', L"BT only Board", OALBLMenuDWORDChoose, &(BSPARGS_START->TechBoardUsage),(VOID*)BSP_ARGS_TECHBOARD_BT,NULL,NULL},
    {L'5', L"Both BT and WLAN", OALBLMenuDWORDChoose, &(BSPARGS_START->TechBoardUsage),(VOID*)BSP_ARGS_TECHBOARD_BT_WLAN,NULL,NULL},
    {L'Q', L"Quit",NULL,NULL,NULL,NULL,NULL},
    
    {0,NULL,NULL,NULL,NULL,NULL,NULL}
};

void DoChangeFreq(int i);
DWORD ChangeFreq(MENU_ITEM *pItem)
{
    DoChangeFreq((int)pItem->pParam2);
    OALBLMenuDWORDChoose( pItem);
    return 0;    
}

MENU_ITEM  SystemFreqMenu[]=
{
    {L'1', _T( BSP_ARGS_RUN_FREQ_IPM_DESC), ChangeFreq,&(BSPARGS_START->RunFreq),(VOID*)BSP_ARGS_RUN_FREQ_IPM,NULL,NULL},
    {L'2', _T( BSP_ARGS_RUN_FREQ_1_DESC), ChangeFreq, &(BSPARGS_START->RunFreq),(VOID *) BSP_ARGS_RUN_FREQ_1,NULL,NULL},
    {L'3', _T( BSP_ARGS_RUN_FREQ_2_DESC), ChangeFreq, &(BSPARGS_START->RunFreq),(VOID *) BSP_ARGS_RUN_FREQ_2,NULL,NULL},
    {L'4', _T( BSP_ARGS_RUN_FREQ_3_DESC), ChangeFreq, &(BSPARGS_START->RunFreq),(VOID *) BSP_ARGS_RUN_FREQ_3,NULL,NULL},
    {L'5', _T( BSP_ARGS_RUN_FREQ_4_DESC), ChangeFreq, &(BSPARGS_START->RunFreq),(VOID *) BSP_ARGS_RUN_FREQ_4,NULL,NULL},
    {L'6', _T( BSP_ARGS_RUN_FREQ_5_DESC), ChangeFreq, &(BSPARGS_START->RunFreq),(VOID *) BSP_ARGS_RUN_FREQ_5,NULL,NULL},
    {L'7', _T( BSP_ARGS_RUN_FREQ_6_DESC), ChangeFreq, &(BSPARGS_START->RunFreq),(VOID *) BSP_ARGS_RUN_FREQ_6,NULL,NULL},

    {L'Q', L"Quit",NULL,NULL,NULL,NULL,NULL},
    {0,NULL,NULL,NULL,NULL,NULL,NULL}			
};


MENU_ITEM *GetBSPArg();
void ResetDefaultBSPCFG(g_pBSPArgs);
BOOL StoreBSPCFG(BSP_ARGS *BSPCFG);

DWORD ResetBSPCFG(MENU_ITEM *pItem)
{
    if(AreYouSure())
    {
        ResetDefaultBSPCFG(g_pBSPArgs);
        GetBSPArg();
    }
    return 0;
}

DWORD SaveBSPCFG(MENU_ITEM *pItem)
{

    if(StoreBSPCFG(g_pBSPArgs))
    {
        EdbgOutputDebugString("\r\nSave configuration Success\r\n");
    }else
    {
        EdbgOutputDebugString("\r\nSave configuration Fail\r\n");        
    }
    return 0;
}

void SetMACAddress(BSP_ARGS *pEbootCFG);

DWORD SetMAC(MENU_ITEM *p)
{
    SetMACAddress(g_pBSPArgs);
    GetBSPArg();
    return 0;
}
DWORD MenuShow(MENU_ITEM *pItem)
{
    OALBLMenuShow(pItem);
    GetBSPArg();
    return 0;
}

// Number of menu items including the null entry to indicate end of list
#define NUMBER_OF_MENU_ITEMS 22
MENU_ITEM *GetBSPArg()
{
    static MENU_ITEM menu[NUMBER_OF_MENU_ITEMS];    //Make sure this size larger than the below item numbers
    MENU_ITEM *pItem = menu;
    memset(menu, 0, sizeof(menu));
    
    InitMenuItem(pItem++, L'P',L"LCD Panel:  (%s)", MenuShow, (void*)GetLCDPanelName(g_pBSPArgs->eBootCFG.drvCfg[CFG_LCD_PANEL]), LCDPanelMenu, NULL, NULL);
    InitMenuItem(pItem++, L'B',L"Bit Blit:  (%s)", MenuShow, (void*)GetBlitName(BSPARGS_START->DefaultBlit), BlitMenu, NULL, NULL);

    InitMenuItem(pItem++, L'T',L"KITL(Image Download) Transport: (%s)", MenuShow,(VOID*) GetMenuTextP2EQKey(KITLTransMenu,(DWORD)g_pBSPArgs->kitl.devLoc.PhysicalLoc), KITLTransMenu,NULL, NULL);
    InitMenuItem(pItem++, L'K',L"Enable KITL: (%s)",OALBLMenuEnableMASK32,g_pBSPArgs->kitl.flags&OAL_KITL_FLAGS_ENABLED?L"Enabled":L"Disabled", &g_pBSPArgs->kitl.flags,(VOID*)OAL_KITL_FLAGS_ENABLED , NULL);
    InitMenuItem(pItem++, L'I',L"Enable IMM driver: (%s)",OALBLMenuEnableBOOL,g_pBSPArgs->IMM_ENABLE?L"Enabled":L"Disabled", &g_pBSPArgs->IMM_ENABLE,NULL , NULL);
    InitMenuItem(pItem++, L'V',L"Enable VBridge: (%s)",OALBLMenuEnableMASK32,g_pBSPArgs->kitl.flags&OAL_KITL_FLAGS_VMINI?L"Enabled":L"Disabled", &g_pBSPArgs->kitl.flags,(VOID*) OAL_KITL_FLAGS_VMINI, NULL);
    InitMenuItem(pItem++, L'M',L"MAC address: (%X:%X:%X)",SetMAC, (VOID*)g_pBSPArgs->kitl.mac[0],(VOID*)g_pBSPArgs->kitl.mac[1],(VOID*)g_pBSPArgs->kitl.mac[2],NULL);
    
    InitMenuItem(pItem++, L'F',L"System frequence: %s", MenuShow, (VOID*)GetMenuTextP2EQKey(SystemFreqMenu,g_pBSPArgs->RunFreq), SystemFreqMenu, NULL, NULL);

    //Disable IPM Configure Items in Eoobt Menu
    //InitMenuItem(pItem++, L'1',L"Enable D0CS IDLE: (%s)",OALBLMenuEnableMASK32,g_pBSPArgs->LowPowerModeIdle&BSP_ARGS_IDLE_D0CS?L"Enabled":L"Disabled", &g_pBSPArgs->LowPowerModeIdle,(VOID*)BSP_ARGS_IDLE_D0CS , NULL);
    //InitMenuItem(pItem++, L'2', L"Enable D1 IDLE: (%s)", OALBLMenuEnableMASK32, g_pBSPArgs->LowPowerModeIdle & BSP_ARGS_IDLE_D1 ? L"Enabled" : L"Disabled", &g_pBSPArgs->LowPowerModeIdle, (VOID *) BSP_ARGS_IDLE_D1, NULL);
    //InitMenuItem(pItem++, L'3', L"Enable D2 IDLE (Only for SmartPhone): (%s)", OALBLMenuEnableMASK32, g_pBSPArgs->LowPowerModeIdle & BSP_ARGS_IDLE_D2 ? L"Enabled" : L"Disabled", &g_pBSPArgs->LowPowerModeIdle, (VOID *) BSP_ARGS_IDLE_D2, NULL);
    
    InitMenuItem(pItem++, L'O', L"Sensor Select: (%s)", MenuShow, (VOID *) GetMenuTextP2EQKey(SensorMenu, g_pBSPArgs->DefaultSensor), SensorMenu, NULL, NULL);

    InitMenuItem(pItem++, L'G',L"Use Battery: (%s)",OALBLMenuEnableBOOL,g_pBSPArgs->BatteryEnable?L"Enabled":L"Disabled", &g_pBSPArgs->BatteryEnable, NULL , NULL);

    InitMenuItem(pItem++, L'A',L"STUART usage: (%s)",MenuShow, (VOID*)GetMenuTextP2EQKey(STUARTMenu,g_pBSPArgs->STUARTUsage), STUARTMenu,NULL, NULL);
    InitMenuItem(pItem++, L'W', L"Tech Board usage: (%s)", MenuShow, (VOID *) GetMenuTextP2EQKey(BTWLANMenu, g_pBSPArgs->TechBoardUsage), BTWLANMenu, NULL, NULL);	
    InitMenuItem(pItem++, L'E',L"Enable Power Optimization for Golden Board: (%s)",OALBLMenuEnableBOOL,g_pBSPArgs->SpecialECO?L"Enabled":L"Disabled", &g_pBSPArgs->SpecialECO,NULL , NULL);

    InitMenuItem(pItem++, L'X', L"Enable NAND DMA: (%s)", OALBLMenuEnableBOOL, g_pBSPArgs->NAND_DMA_enable?L"Enabled":L"Disabled", &g_pBSPArgs->NAND_DMA_enable, NULL, NULL);
    InitMenuItem(pItem++, L'Y', L"Enable NAND Interrupt: (%s)", OALBLMenuEnableBOOL, g_pBSPArgs->NAND_INTR_enable?L"Enabled":L"Disabled", &g_pBSPArgs->NAND_INTR_enable, NULL, NULL);
    InitMenuItem(pItem++, L'Z', L"Enable Clock Gating Workaround (%s)", OALBLMenuEnableBOOL, g_pBSPArgs->NAND_ClockGatingWA_enable?L"Enabled":L"Disabled", &g_pBSPArgs->NAND_ClockGatingWA_enable, NULL, NULL);

    
    InitMenuItem(pItem++, L'R',L"Reset to factory default configuration", ResetBSPCFG, NULL, NULL, NULL, NULL);
    InitMenuItem(pItem++, L'S',L"Save configuration to FLASH", SaveBSPCFG, NULL, NULL, NULL, NULL);
    InitMenuItem(pItem++, L'Q',L"Quit to Main menu", NULL, NULL, NULL, NULL, NULL);

    //  Indicate the end of the list
    InitMenuItem(pItem++, L'\0',L"", NULL, NULL, NULL, NULL, NULL);

    return menu;
}



DWORD SetBSPArg(MENU_ITEM *pCur)
{
    pCur->pParam1=L"Set up BSP Configuration";
    pCur->pParam2=GetBSPArg();
    OALBLMenuShow(pCur);

    return 0;
}

    /// Will print basic Eboot config options
    ///
void ConfigPrint()
{
    OALLog ( L"LCD Panel (%s)\r\n", GetLCDPanelName(g_pBSPArgs->eBootCFG.drvCfg[CFG_LCD_PANEL]));

    OALLog( L"KITL(Image Download) Transport (%s)\r\n",GetMenuTextP2EQKey(KITLTransMenu,(DWORD)g_pBSPArgs->kitl.devLoc.PhysicalLoc));
    
    OALLog ( L"Enable KITL (%s)\r\n",(g_pBSPArgs->kitl.flags&OAL_KITL_FLAGS_ENABLED?L"Enabled":L"Disabled"));
    OALLog ( L"Enable VBridge (%s)\r\n", (g_pBSPArgs->kitl.flags&OAL_KITL_FLAGS_VMINI?L"Enabled":L"Disabled"));

    OALLog ( L"MAC address: %X-%X-%X-%X-%X-%X\r\n",
                                          g_pBSPArgs->kitl.mac[0] & 0x00FF, g_pBSPArgs->kitl.mac[0] >> 8,
                                          g_pBSPArgs->kitl.mac[1] & 0x00FF, g_pBSPArgs->kitl.mac[1] >> 8,
                                          g_pBSPArgs->kitl.mac[2] & 0x00FF, g_pBSPArgs->kitl.mac[2] >> 8);

    OALLog ( L"System frequence %s\r\n", GetMenuTextP2EQKey(SystemFreqMenu,g_pBSPArgs->RunFreq));

}
